﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using Automator.Runtime;
using Automator.Runtime.Compiler;
using Automator.Tasks.Core;
using Automator.Tasks.Windows;
using ICSharpCode.AvalonEdit.Highlighting;

namespace Automator.Tasks
{
    /// <summary>
    /// Class for executing custom scripts
    /// Defined attributes:
    /// Header: brief description what this code does
    /// Text: text of the script
    /// Language: programming language of the script
    /// </summary>
    public class ScriptTask: Task, ITaskExecutable
    {
        public void Execute(WorkflowExecutionContext context)
        {
            try
            {
                DynamicCompiler compiler = new DynamicCompiler(
                    this.Attributes["Language"].Value.ToString(),
                    this.Attributes["Text"].Value.ToString(), 
                    SourceType.Script);
                
                if (compiler.Errors.Count > 0)
                    throw new Exception(compiler.Errors[0].ToString());
                context.Result = compiler.Execute(context.Result);
            }
            catch (Exception ex)
            {
                throw new TaskExecutionException(ex.Message, ex);
            }
        }
        
        public ScriptTask():
            base()
        {
            this.Title = "Script";
            this.Description = "Execute custom code";
            this.TaskImage = new BitmapImage(new Uri("/Automator.Tasks;component/Resources/script.png", UriKind.Relative));
            this.OutputObject = "Any";

            this.Attributes.Add(new TaskAttributeDefinition() { Key = "Header", Value = String.Empty });
            this.Attributes.Add(new TaskAttributeDefinition() { Key = "Text", Value = String.Empty });
            this.Attributes.Add(new TaskAttributeDefinition() { Key = "Language", Value = "C#" });
        }
        
        public override string CommandText
        {
            get { return Attributes["Header"].Value.ToString().Trim(); }
            set { base.CommandText = value; }
        }
        
        public override bool EditTask()
        {
            base.EditTask();
            ScriptTaskEditWindow window = new ScriptTaskEditWindow();
            window.Owner = Application.Current.MainWindow;
            window.Title = String.Format("Edit {0} Task", this.Title);
            //performing binding to the header
            window.header.ContentPanel.DataContext = this;
            
            window.cmbLanguage.ItemsSource = DynamicCompiler.SourceLanguages;
            window.cmbLanguage.SelectionChanged += delegate(object sender, SelectionChangedEventArgs e)
            {
                switch (window.cmbLanguage.SelectedItem.ToString())
                {
                    case "C#":
                        window.edtText.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("C#");
                        break;
                    case "VB.NET":
                        window.edtText.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("VBNET");
                        break;
                    case "JScript":
                        window.edtText.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("JavaScript");
                        break;
                    default:
                        break;
                }                
            };
            
            window.edtHeader.Text = this.Attributes["Header"].Value.ToString();
            window.edtText.Text = this.Attributes["Text"].Value.ToString();
            window.cmbLanguage.SelectedValue = this.Attributes["Language"].Value.ToString();
            window.footer.BtnOK.Click += delegate { window.DialogResult = true; };
            if (window.ShowDialog() == true)
            {
                this.Attributes["Header"].Value = window.edtHeader.Text.Trim();
                this.Attributes["Text"].Value = window.edtText.Text.Trim();
                this.Attributes["Language"].Value = window.cmbLanguage.SelectedItem.ToString();
                this.CommandText = String.Empty;
                return true;
            }
            else return false;
        }
    }
}
